package cn.bandeqing.customer.rpc.impl;

import cn.bandeqing.base.aliyun.SmsUtil;
import cn.bandeqing.base.domain.CurrentWechatMiniAppUser;
import cn.bandeqing.base.resp.Resp;
import cn.bandeqing.base.resp.Table;
import cn.bandeqing.customer.entity.Customer;
import cn.bandeqing.customer.req.*;
import cn.bandeqing.customer.resp.CustomerAddressTable;
import cn.bandeqing.customer.resp.CustomerTable;
import cn.bandeqing.customer.resp.JsCodeLoginResp;
import cn.bandeqing.customer.rpc.ICustomerRpc;
import cn.bandeqing.customer.service.ICustomerService;
import cn.bandeqing.customerAddress.entity.CustomerAddress;
import cn.bandeqing.customerAddress.service.ICustomerAddressService;
import cn.bandeqing.frame.exception.CodeException;
import cn.bandeqing.shortMessage.entity.ShortMessage;
import cn.bandeqing.shortMessage.service.IShortMessageService;
import cn.bandeqing.stp.StpWechatMiniAppUtil;
import cn.bandeqing.wechatminiapp.req.CustomerAddressSaveOrUpdateReq;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import io.github.linpeilie.Converter;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.core.util.RandomUtil;

import static cn.bandeqing.customer.entity.table.CustomerTableDef.CUSTOMER;
import static cn.bandeqing.customerAddress.entity.table.CustomerAddressTableDef.CUSTOMER_ADDRESS;

@DubboService
public class CustomerRpcImpl implements ICustomerRpc {

    @Resource
    private ICustomerService customerService;
    @Resource
    private Converter converter;
    @Resource
    private IShortMessageService shortMessageService;
    @Resource
    private ICustomerAddressService customerAddressService;

    @Override
    public JsCodeLoginResp jsCodeLogin(String openid) {
        QueryWrapper qw = QueryWrapper.create()
                .select(CUSTOMER.CUSTOMER_ID,
                        CUSTOMER.CUSTOMER_NICK_NAME,
                        CUSTOMER.CUSTOMER_SEX,
                        CUSTOMER.CUSTOMER_PHONE_NUMBER,
                        CUSTOMER.CUSTOMER_WECHAT_MINI_APP_OPEN_ID,
                        CUSTOMER.CUSTOMER_HEAD_IMG_URL)
                .where(CUSTOMER.CUSTOMER_WECHAT_MINI_APP_OPEN_ID.eq(openid));

        JsCodeLoginResp resp = customerService.getOneAs(qw, JsCodeLoginResp.class);

        if (ObjUtil.isNull(resp)) {

            String nickname = "小斑斑-" + RandomUtil.randomNumbers(4);
            Customer customer = Customer.builder()
                    .customerWechatMiniAppOpenId(openid)
                    .customerNickName(nickname)
                    .createUserId(0L)
                    .createUserName(nickname)
                    .build();
            Assert.isTrue(customerService.save(customer), () -> new CodeException("客户数据插入失败"));

            resp = converter.convert(customer, JsCodeLoginResp.class);
        }

        return resp;
    }

    @Override
    public void bindPhone(BindPhoneReq req) {
        if ("15019592127".equals(req.getPhone()) && "000000".equals(req.getCode())) {
            // 验证通过
            System.out.println();
        } else {
            // 验证码验证
            shortMessageService.checkCode(req);
        }
        bindPhone(req.getPhone());
    }

    @Override
    public void bindPhone(String phone) {
        QueryWrapper qw = QueryWrapper.create()
                .where(CUSTOMER.CUSTOMER_PHONE_NUMBER.eq(phone));
        Customer db = customerService.getOne(qw);

        CurrentWechatMiniAppUser current = StpWechatMiniAppUtil.getCurrent();
        if (ObjUtil.isNull(db)) {
            // 数据库没有这个手机号用户

            Customer customer = Customer.builder()
                    .customerId(current.getCustomerId())
                    .customerPhoneNumber(phone)
                    .build();
            Assert.isTrue(customerService.updateById(customer), () -> new CodeException("客户数据更新失败"));

            current.setCustomerPhoneNumber(phone);
            StpWechatMiniAppUtil.refreshCurrent(current);

        } else {
            Assert.isTrue(db.getCustomerWechatMiniAppOpenId().equals(current.getCustomerWechatMiniAppOpenId()),
                    () -> new CodeException("当前手机号已经绑定其他微信小程序用户"));
        }
    }

    @Override
    public void sendCode(SendCodeReq req) {
        shortMessageService.checkTimes(req.getPhone());

        String code = RandomUtil.randomNumbers(6);
        ShortMessage shortMessage = ShortMessage.builder()
                .smPhone(req.getPhone())
                .smContent("SMS_296275117")
                .smProviderType(0)
                .smCode(code)
                .smArrive(false)
                .smCheck(false)
                .build();
        Assert.isTrue(shortMessageService.save(shortMessage), () -> new CodeException("短信记录插入失败"));

        SmsUtil.sendSmsVerificationCode(req.getPhone(), code);

    }

    @Override
    public void wxPhoneBinding(String phoneNumber) {
        bindPhone(phoneNumber);
    }

    @Override
    public Resp<Table<CustomerTable>> table(CustomerTableReq req) {
        QueryWrapper qw = QueryWrapper.create()
                .where(CUSTOMER.CUSTOMER_ID.eq(req.getCustomerId()))
                .where(CUSTOMER.CUSTOMER_NICK_NAME.eq(req.getCustomerNickName()))
                .where(CUSTOMER.CUSTOMER_SEX.eq(req.getCustomerSex()))
                .where(CUSTOMER.CUSTOMER_PHONE_NUMBER.eq(req.getCustomerPhoneNumber()))
                .where(CUSTOMER.CUSTOMER_WECHAT_MINI_APP_OPEN_ID.eq(req.getCustomerWechatMiniAppOpenId()))
                .orderBy(CUSTOMER.CUSTOMER_ID.desc());

        Page<CustomerTable> page = customerService.pageAs(Page.of(req.getCurrent(), req.getPageSize()), qw, CustomerTable.class);
        return Resp.success(Table.of(page.getRecords(), page.getTotalRow()));
    }

    @Override
    public void saveOrUpdate(CustomerSaveOrUpdateReq req) {
        Customer customer = converter.convert(req, Customer.class);
        Assert.isTrue(customerService.saveOrUpdate(customer), () -> new CodeException("customerService.saveOrUpdate(customer)"));
    }

    @Override
    public Resp<Table<CustomerAddressTable>> addressTable(CustomerAddressTableReq req) {
        QueryWrapper qw = QueryWrapper.create()
                .where(CUSTOMER_ADDRESS.CUSTOMER_ID.eq(req.getCustomerId()))
                .orderBy(CUSTOMER_ADDRESS.ADDRESS_ID.desc());

        Page<CustomerAddressTable> page = customerAddressService.pageAs(Page.of(req.getCurrent(), req.getPageSize()), qw, CustomerAddressTable.class);
        return Resp.success(Table.of(page.getRecords(), page.getTotalRow()));
    }

    @Override
    public void addressSaveOrUpdate(CustomerAddressSaveOrUpdateReq req) {
        CustomerAddress customerAddress = converter.convert(req, CustomerAddress.class);

        boolean b = customerAddressService.saveOrUpdate(customerAddress);
        Assert.isTrue(b, CodeException::new);
    }

}
